<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>集合</title>
	</head>
	<body>
	</body>
</html>
<script type="text/javascript">
	/*
	 
	 集合:
		特点:是由一组无序的,不能重复的元素构成,
		常见方式是哈希表
		
	特殊的数组:
			特殊之处在于里面的元素没有顺序,也不能重复
			没有顺序意味着不能通过下表值进行访问,不能重复意味着相同的对象在集合中只会存在一份
	ES6中的SET类
	ES5中的Array类
	
	集合的常见操作:
			add(value):向集合中添加一个新的项.,
			remove(value):从集合移除一个值,
			has(value):如果值在集合中,返回true,否则返回false,
			clear():移除集合中所以的项,
			size():返回集合所有包含元素的数量,与数组的length属性类似,
			values():返回一个包含集合中所有值的数组,
			
	 
	 
	 **/
	 function Set(){
		 // 属性
		 this.items={}
		 // 方法
		 // add 方法
		 Set.prototype.add = function(value){
			 // 判断当前集合中是否包含该元素
			 if(this.has(value)) return false
			 this.items[value]=value
			 return true
		 }
		 
		 // has 方法
		 Set.prototype.has = function(value){
			 return this.items.hasOwnProperty(value)
		 }
		 // remove 方法
		 Set.prototype.remove = function(value){
			 // 判断当前集合中是否包含该元素
			 if(!this.has(value)) return false
			 // 将元素删除元素
			 delete this.items[value]
			 return true
		 }
		 // clear方法
		 Set.prototype.clear = function(){
			 this.items={}
		 }
		 // size方法
		 Set.prototype.size = function(){
			 return Object.keys(this.items).length
		 }
		 // 获取集合中所有的值
		 Set.prototype.values = function(){
			 return Object.keys(this.items)
		 }
		 // 集合间的操作
		 // 并集
		 Set.prototype.unicon= function(otherSet){
			 // this:集合对象A
			 // otherSet集合对象B
			 // 1.创建新的集合
			 var uniconSet = new Set();
			 
			 // 2.将A集合中所有的元素添加到新的集合当中
			 var values=this.values()
			 for (var i = 0;i<values.length;i++) {
			 	uniconSet.add(values[i])
			 }
			 values=otherSet.values()
			 // 3.取出B集合中的元素，判断是否需要集到新集合
			 for (var i=0;i<values.length;i++) {
			 	uniconSet.add(values[i])
			 }
			  return  uniconSet
		 }
		 
		 // 交集 
		 Set.prototype.intersection=function(otherSet){
			 // this:集合对象A
			 // otherSet集合对象B
			 
			 //1.创建新的集合 
			 var intersectionSet = new Set();
			 
			 // 2.从A集合中取出一个个元素，判断是否同时存在于集合B中，存入新集合中
			 var values=this.values()
			 for (var i =0;i < values.length;i++) {
			 	var item=values[i]
				if(otherSet.has(item)){
					intersectionSet.add(item)
				}
			 }
			 return intersectionSet
		 }
		 
		 // 差集
		 Set.prototype.difference = function(otherSet){
			 // this:集合对象A
			 // otherSet集合对象B
			 
			 //1.创建新的集合 
			 var differenceSet = new Set();
			 
			 // 2.从集合A中取出一个个元素，判断是否存在集合B中，不存在，放入新集合中
			 var values=this.values()
			 for (var i =0;i < values.length;i++) {
			 	var item=values[i]
			 	if(!otherSet.has(item)){
			 		differenceSet.add(item)
			 	}
			 }
			 return differenceSet
		 }
		 // 子集
		 Set.prototype.subset = function(otherSet){
			 // this:集合对象A
			 // otherSet集合对象B
			 // 遍历集合A所有的元素，如果发现，集合A中的元素，在集合B中不存在，那么return false 
			 // 遍历完成整个集合没有false，则return true
			 //1.创建新的集合 
			  var values=this.values()
			  
			  for (var i = 0; i < values.length; i++) {
					var item = 	values[i]
					if(!otherSet.has(item)){
						return false
					}
			  }
			  return true
		 }
		 
	 }
	 
	 // 测试
	 
	 // 1.创建
	 // var set = new Set();
	 // set.add('aaa')
	 // set.add('bbb')
	 // set.add('aaa')
	 // // alert(set.add('aaa'))
	 // // alert(set.add('bbb'))
	 // // alert(set.add('aaa'))
	 
	 // alert(set.values())
	 
	 /*
	 集合间操作
		集合间通常有入力操作：
			并集：对于给定的两个集合，返回一个包含两个集合中所有元素的新集合
			交集：对于给定的两个集合，返回一个包含两个集合中共有的元素的新集合
			差集：对于给定的的两个集合，返回一个所有存在于第一个集合且不存在第二个集合的操作子集
			子集：验证一个给定集合是否是另一个集合的子集。
	 */
	
	
	// 创建两个集合，并添加元素
	
	var setA = new Set();
	 setA.add('ccc')
	 setA.add('ddd')
	 setA.add('fff')
	 var setB = new Set();
	 setB.add('ccc')
	 setB.add('dddd')
	 setB.add('ddd')
	 // 2.求两个集合的并集
	 // var uniconSet = setB.unicon(setA)
	 //  alert(uniconSet.values())
	 // 交集
	 var intersection = setA.intersection(setB)
	 alert(intersection.values())
	 // 差集
	 var difference = setA.difference(setB)
	 alert(difference.values())
	 
	 // 子集
	 alert(setA.subset(setB))
	 
</script>
